/***************************************************************************************************
 *
 * Project: HZFlashcards
 *
 * Class: HanZiDisplayPanel
 *
 * File name: HanZiDisplayPanel.java
 *
 * Sep 5, 2007
 *
 **************************************************************************************************/

package com.eastmountain.chinese.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import com.eastmountain.chinese.common.FlashCardLessonSet;
import com.eastmountain.chinese.db.exceptions.DBAccessException;
import com.eastmountain.chinese.db.flashcards.records.ChineseElementProperties;
import com.eastmountain.chinese.gui.controllers.HZWindowAdapter;
import com.eastmountain.chinese.gui.controllers.ToolBarButtons;
import com.eastmountain.chinese.gui.controllers.ToolBarPanel;
import com.eastmountain.chinese.observable.HZFlashcardsDataModel;
import com.eastmountain.util.logging.LoggerUtils;

/***************************************************************************************************
 *
 * CLASS HanZiDisplayPanel
 *
 **************************************************************************************************/

public class HanZiDisplayPanel extends JPanel implements Observer {

    /***************************************
     *     serialVersionUID  - Dec 9, 2007
     ***************************************/
    private static final long serialVersionUID = 2404967259107405705L;

    private HZFlashcardsDataModel hzFlashcardsDataModel = null;
    
    private static String dbIndicator;

    private ToolBarPanel toolBarPanel = null;

    private HanZiDrawingSurface hanZiDrawingSurface;

    private Class currentFlashCardClass;
    
    private Vector<ChineseElementProperties> lessonFlashCards;

    private FlashCardLessonSet flashCardLessonSet = new FlashCardLessonSet();
    private FlashCardLessonSet shuffledFlashCardLessons;
    
    private Timer playerTimer;
    
    private static final int PAUSE_BEFORE_BEGINING   = 150; // milliseconds
    private static final int NEXT_SOUND_INTERVAL     = 2500; // milliseconds
    private static final String NEXT_ACTION          = "Next";
    
    private DoNextSound doNextSound = null;


    private static String projectName = "hzflashcards";
    protected static Logger logger = LoggerUtils.setUpLogger( projectName );

    /***********************************************************************************************
     *
     * HanZiDisplayPanel
     *
     **********************************************************************************************/

    public HanZiDisplayPanel() {

        // TODO fix definitions
        
        logger.setLevel( Level.WARNING );
        
        hzFlashcardsDataModel = HZFlashcardsDataModel.getInstance( "CHPODS" );
        hzFlashcardsDataModel.addObserver( this );
        
        doNextSound = new DoNextSound( this );

        //lessonStatus = new LessonStatus();

        setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) );

        // TODO Recover from null returned by the following method call
        
        try {

            add( Box.createVerticalGlue() );

            hanZiDrawingSurface = new HanZiDrawingSurface();
            hanZiDrawingSurface.setPreferredSize( new Dimension( 150, 75 ) );

            add( hanZiDrawingSurface, BorderLayout.CENTER );
            
            add( Box.createVerticalGlue() );
            
            toolBarPanel = new ToolBarPanel( this );
            
            add( toolBarPanel, BorderLayout.PAGE_END );

            flashCardLessonSet = hzFlashcardsDataModel.createInitialFlashCardLessonSet();

            init();
        
        } catch (DBAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    private void init() throws DBAccessException {
        
        ChineseElementProperties lessonFlashCard;

        lessonFlashCard
            = flashCardLessonSet.firstFlashCard();
            
        if ( ! ( lessonFlashCard == null ) ) {
            
            currentFlashCardClass = lessonFlashCard.getClass();
            
            hanZiDrawingSurface.setCurrentFlashCardClass( currentFlashCardClass );

            setToolBarButtonStates( currentFlashCardClass );
            
        	display( lessonFlashCard );

        } else {

            //  TODO create a new exception
            
        	throw new DBAccessException( "Error in initializing HanZiDisplayPanel" );

        	//System.exit( 12 );

        }

    }

    /***********************************************************************************************
     *
     * display
     *
     **********************************************************************************************/

    public void display( ChineseElementProperties chineseElementProperties ) {

        // String jaString = "\u65e5\u672c\u8a9e\u6587\u5b57\u5217";
    	

        hanZiDrawingSurface.display( chineseElementProperties );
        
        flashCardLessonSet.setLessonStatus( chineseElementProperties );
        
        hzFlashcardsDataModel.setChanged();
        hzFlashcardsDataModel.setCurrentChineseElementProperties( chineseElementProperties );

    }

    private String extractElement( String elementIn ) {

        String elementOut = "";

        elementOut = elementIn.trim();

        if ( "".equals( elementOut ) ) {

            elementOut = "Missing";
        }

        return elementOut;

    }

    /***********************************************************************************************
     *
     * previousLesson - // TODO add previous lesson logic
     *
     **********************************************************************************************/

    public void previousLesson() {

        display( flashCardLessonSet.previousLesson() );

    }

    /***********************************************************************************************
     *
     * previous
     *
     **********************************************************************************************/

    public void previous() {

        display( flashCardLessonSet.previousFlashCard() );

    }

    /***********************************************************************************************
     *
     * next
     *
     **********************************************************************************************/

    public void next() {

        display( flashCardLessonSet.nextFlashCard() );

    }

    /***********************************************************************************************
     *
     * nextLesson - // TODO add next lesson logic
     *
     **********************************************************************************************/

    public void nextLesson() {

        display( flashCardLessonSet.nextLesson() );

    }

    public void flip() {

        hanZiDrawingSurface.turn();

    }

    /***********************************************************************************************
     *
     * shuffle
     *
     **********************************************************************************************/

    public void shuffle() {
		
		System.out.println( "***  HanZiDisplayPanel.shuffle()" );

        // TODO what do we do here, if anything?    private Vector<ChineseElementProperties> shuffledFlashCardLessons;

		Vector<ChineseElementProperties> flashCardsInToto = hzFlashcardsDataModel.shuffleFlashcards();
	    
	    shuffledFlashCardLessons = new FlashCardLessonSet();
	    shuffledFlashCardLessons.add( flashCardsInToto );
	    flashCardLessonSet = shuffledFlashCardLessons;
        
		try {
			
			init();
			
		} catch (DBAccessException e) {
			
			// TODO Auto-generated catch block
			e.printStackTrace();
			
		}


    }
    
    /***********************************************************************************************
     *
     * question
     *
     **********************************************************************************************/

    public void question() {

        System.out.println( "!!! question  !!!!" );

        hzFlashcardsDataModel.addElementToReviewList();

    }
    
    /***********************************************************************************************
     *
     * playDrill
     *
     **********************************************************************************************/

    public void playDrill() {      

        // TODO maybe create SwingTimer only once

        playerTimer = new Timer( NEXT_SOUND_INTERVAL, doNextSound );
        playerTimer.setInitialDelay( PAUSE_BEFORE_BEGINING );
        
        playerTimer.start();
        
    }
    
    /***********************************************************************************************
     *
     * stopPlay
     *
     **********************************************************************************************/

    public void stopPlay() {
        
        playerTimer.stop();
        
    }

    private void setToolBarButtonStates( Class currentFlashCardClass ) {
        
        if ( hzFlashcardsDataModel.multipleLessons() ) {

            toolBarPanel.enableDisableButton( ToolBarButtons.PREVIOUS_LESSON, true );
            toolBarPanel.enableDisableButton( ToolBarButtons.NEXT_LESSON, true );

        } else {

            toolBarPanel.enableDisableButton( ToolBarButtons.PREVIOUS_LESSON, false );
            toolBarPanel.enableDisableButton( ToolBarButtons.NEXT_LESSON, false );

        }
        
        if ( currentFlashCardClass.equals( String.class ) ) {
            
            
        }
        
    }

    /***********************************************************************************************
     *
     * update - Observer interface
     *
     **********************************************************************************************/

    public void update( Observable o, Object arg ) {

        // TODO Handle argument checking within an aspect

        System.out.println( "!!! HanZiDisplayPanel.update() invoked  !!!!" );

        if ( arg == null ) {

            System.out.println( "   --- arg is null ---" );

            return;

        }

        System.out.println( "Class name: " + arg.getClass().getSimpleName() );

        if ( "FlashCardLessonSet".equals( arg.getClass().getSimpleName() ) ) {

            flashCardLessonSet = (FlashCardLessonSet) arg;

            if ( flashCardLessonSet.isEmpty() ) {

                System.out.println( "=== HanZiDisplayPanel.update(): flashCardLessonSet is empty!" );

            } else {
            
                try {
                	
					init();
					
				} catch (DBAccessException e) {
					
					// TODO Auto-generated catch block
					e.printStackTrace();
					
				}
            
            }
            
        }

    }

    /***********************************************************************************************
     *
     *   createAndShowGUI: for testing purposes
     *
     **********************************************************************************************/
    
    public static HanZiDisplayPanel createAndShowGUI() {

        HanZiDisplayPanel hanZiDisplayPanel = new HanZiDisplayPanel();

        hanZiDisplayPanel.frameItForTest( dbIndicator );
        
        return( hanZiDisplayPanel );

    }

    /***********************************************************************************************
     *
     *   frameItForTest: for testing purposes
     *
     **********************************************************************************************/

    public void frameItForTest( String dbIndicator ) {
        
        int w,h;
        
        JFrame.setDefaultLookAndFeelDecorated( true );

        JFrame frame = new JFrame( "Test frameTitle" );
        frame.addWindowListener( new HZWindowAdapter( frame ) );

        setOpaque( true );
        //frame.setJMenuBar( flashcardsMenuBar );

        frame.getContentPane().add( this );

        // Display the window.

        frame.pack();

        w = getWidth();
        h = getHeight();

        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation( dimension.width / 2 - w / 2, dimension.height / 2 - h / 2 );
        
        frame.toFront(); 
        frame.setVisible( true );

        hzFlashcardsDataModel.setMainFrame( frame );
 
    }

    /***********************************************************************************************
     *
     *   main: for testing purposes
     *
     **********************************************************************************************/

    public static void main( String[] argv ) {
        
        // send in db indicator
        
        String dbIndicator;

        if ( argv.length == 0 ) {

            System.err.println( "Usage: java HanZiDisplayPanel DataBase Indicator" );
            System.exit( 12 );

        } else {

            System.out.println( "Arg 1: " + argv[ 0 ] );
            
            dbIndicator = argv[ 0 ];
            
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            } );

        }
        
    }

}


/***********************************************************************************
 *
 *  Class DoNextSound
 *
 **********************************************************************************/

class DoNextSound implements ActionListener {

    private HanZiDisplayPanel hanZiDisplayPanel;

    /***********************************************************************************************
     *
     *   DoNextSound
     *
     **********************************************************************************************/

    public DoNextSound( HanZiDisplayPanel hanZiDisplayPanel ) {

        this.hanZiDisplayPanel = hanZiDisplayPanel;
        
    }

    /***********************************************************************************************
     *
     *   actionPerformed
     *
     **********************************************************************************************/

    public void actionPerformed( ActionEvent arg0 ) {

        hanZiDisplayPanel.next();
            
    }

}

